#ifndef MS575__ALGBASE_H
#define MS575__ALGBASE_H
#include "ms575_parameterclass.h"
#include "ms575_edgedetect.h"

using namespace MeasurE575;
//const string dir_edge_extraction_parameters("/mnt/hgfs/linuxsharefiles/testImages/images/4.1/575MeasureData/edge_extraction_parameters/");
//const string dir_template_classifier_model( "/mnt/hgfs/linuxsharefiles/testImages/images/4.1/575MeasureData/template_classifier_model/");
//const string dir_template_feature_model( "/mnt/hgfs/linuxsharefiles/testImages/images/4.1/575MeasureData/template_feature_model/");
//const string dir_template_images( "/mnt/hgfs/linuxsharefiles/testImages/images/4.1/575MeasureData/template_images/");

namespace MeasurE575
{
    class AlgBase
    {
    public:
        AlgBase()=default;
        AlgBase(int n);
        virtual ~AlgBase();
        static void InitFunAll(const int n);

        /***********************************************************************
     *  @function InitPath
     *  @brief
     *  @param
     *  @return
    ***********************************************************************/
        static bool InitPath(const std::string &path);

        /***********************************************************************
          *  @function SetTemplatePath
          *  @brief    设置s_model文件夹的目录
          *  @param    path：s_model文件夹的目录
          *  @return
         ***********************************************************************/
        static bool SetTemplatePath(const std::string &path);

        /***********************************************************************
          *  @function SetStandarVal
          *  @brief    设置标准值
          *  @param
          *  @return
         ***********************************************************************/
        static void SetStandardVal(const std::map<string, float> standardVal);

        /***********************************************************************
          *  @function SetWorkpieceInfo
          *  @brief
          *  @param
          *  @return
        ***********************************************************************/
        static void SetWorkpieceInfo(const std::string &modeName,
                              const std::string &workpieceType = "");

        /***********************************************************************
     *  @function
     *  @brief
     *  @param
     *  @return
    ***********************************************************************/
        static bool LoadFitPara();

        static vector<std::string> LoadFiles(const QString &path, QString ext);

        /***********************************************************************
     *  @function
     *  @brief
     *  @param
     *  @return
    ***********************************************************************/
        static void InitStandardVal(const std::map<string, float> standardVal);

        static std::vector< std::shared_ptr<std::condition_variable>> cvarptrVec;
        static std::vector < std::shared_ptr<std::mutex>  > mtxptrVec;
        static std::vector< std::shared_ptr<std::condition_variable>> cvarptrhighVec;
        static std::vector < std::shared_ptr<std::mutex>  > mtxptrhighVec;
        static std::vector <bool> flagVec;
        static std::vector <bool> flaghighVec;
        static void setNumberOfAlg(const int n);
        void TemplateMatch(cv::Mat &img, ParameterClass &obj, std::vector<cv::Rect> &rangVec);

        void CoordinateTransformationRelateToDot(const std::vector<Point2f> &ptsVec,
                                                          const Point2f &ptsIn,
                                                          Point2f &ptsOut);
        void CoordinateTransformation(std::vector<cv::Point2f> &ptsVec, cv::Point2f &ptsIn,cv::Point2f &ptsOut);
        inline void ImageCoordinateTransformation(std::vector<cv::Point> &ptsInVec,std::vector<cv::Rect> &rangVec)
        {
            for(auto ptr=ptsInVec.begin();ptr!=ptsInVec.end();ptr++)
            {
                ptr->x+=static_cast<int>(rangVec[0].x);
                ptr->y+=static_cast<int>(rangVec[0].y);
            }
        }

        inline void ImageCoordinateTransformation(std::vector<cv::Point2f> &ptsInVec,std::vector<cv::Rect> &rangVec)
        {
            for(auto ptr=ptsInVec.begin();ptr!=ptsInVec.end();ptr++)
            {
                ptr->x+=static_cast<float>(rangVec[0].x);
                ptr->y+=static_cast<float>(rangVec[0].y);
            }
        }
        static void clearAllflag(int id);

        float CalcMeasureDistance(const vector<float> &coefficient, float measureItem);

    /***********************************************************************
     *  @function CalcPixelAccordExpectDist
     *  @brief
     *  @param
     *  @return
    ***********************************************************************/
        float CalcPixelAccordExpectDist(const vector<float> &coefficient,
                                  float expectDist);

    /***********************************************************************
     *  @function CalcPosition
     *  @brief
     *  @param
     *  @return
    ***********************************************************************/
        float CalcPosition(const std::string &measureItemX,
                           const std::string &measureItemY,
                           const std::string &measureItemPos,
                           const std::string &prefix,
                           edgedetect &obj,
                           float expectRealDistX,
                           float expectRealDistY,
                           float predictPixelX,
                           float predictPixelY,
                           std::map<string, float> &measRes);
    protected:
        static std::vector<std::vector<Point2f>> datumBackVec;
        static std::vector<std::vector<Point2f>> datumHighVec;
        static once_flag m_flag;
        static std::vector<ParameterClass> m_dataAllVec;

        static once_flag               m_setStandardValOnceFlag         ;
        static std::string             m_dir_edge_extraction_parameters ;
        static std::string             m_dir_template_classifier_model  ;
        static std::string             m_dir_template_feature_model     ;
        static std::string             m_dir_template_images            ;
        static std::map<std::string, std::vector<float>> m_phypixpara   ;

    public:
        static string                  m_dir_distance_fitting_model     ;
        static std::map<string, float> m_standardValMap                 ;
        static bool                    m_isSetWorkpieceInfo             ;
        static bool                    m_isLoadXml                      ;
        static string                  m_modeName                       ;
        static string                  m_xmlFileNamePre                 ;

    };
}
#endif //MS575_ALGBASE_H
